type NullWrap<T> = T | null | undefined;
type EventHandler<T = Event> = (event: T) => void;

type EventNames = 'flick' | 'refresh' | 'scrollStart' | 'scroll' | 'scrollEnd' | 'destroy';

interface PullDownRefreshOption {
  threshold: number;
  stop: number;
}

interface MouseWheelOption {
  speed: number;
  invert: boolean;
  easeTime: number;
}

interface Options {
  startX: number;
  startY: number; // 起始位置
  scrollX: boolean;
  scrollY: boolean; // 允许纵向滚动
  freeScroll: boolean; // 允许自由滚动
  // directionLockThreshold: 5,
  // eventPassthrough: '',
  // click: boolean;
  tap: boolean | string; // 点击的时候派发一个tap事件
  // bounce: true,
  bounceTime: number;
  momentum: boolean;
  momentumLimitTime: number;
  momentumLimitDistance: number;
  swipeTime: number;
  swipeBounceTime: number;
  deceleration: number;
  flickLimitTime: number;
  flickLimitDistance: number;
  resizePolling: number; // 当发生resize事件后，延迟60ms重新计算bscroll
  // probeType: 0,
  preventDefault: boolean;
  stopPropagation: boolean;
  preventDefaultException: { [key: string]: RegExp };
  // HWCompositing: true,
  // useTransition: true,
  // useTransform: true,
  bindToWrapper: boolean;
  // disableMouse: hasTouch,
  // disableTouch: !hasTouch,
  observeDOM: boolean;
  autoBlur: boolean; // 自动让激活的元素失去焦点

  // scrollbar: false,
  /**
   * for pull down and refresh
   * pullDownRefresh: {
   *   threshold: 50,
   *   stop: 20
   * }
   */
  pullDownRefresh: boolean | PullDownRefreshOption;
  /**
   * for pull up and load
   * pullUpLoad: 50
   */
  pullUpLoad: boolean | number;
  /**
   * for mouse wheel
   * mouseWheel: {
   *   speed: 20,
   *   invert: false,
   *   easeTime: 300
   * }
   */
  mouseWheel: MouseWheelOption | boolean;
}

interface offsetInfo {
  readonly left: number;
  readonly top: number;
}

interface RectInfo extends offsetInfo {
  readonly width: number;
  readonly height: number;
}

interface MoveBase {
  moving: boolean;
  inTransition: boolean;
  startX: number;
  pointX: number;
  x: number;
  directionX: number;
  absStartX: number;
  startY: number;
  pointY: number;
  y: number;
  directionY: number;
  absStartY: number;
  startTime: number;
  endTime: number;
}


interface RectBoundInfo {
  wrapperHeight: number;
  wrapperOffset: offsetInfo;
  scrollerHeight: number;
  minScrollY: number;
  maxScrollY: number;
  relativeY: number;
}

interface momentumInfo { destination: number; duration: number; needReset: boolean; }

type NoNumberCSSStyleDeclaration = Exclude<keyof CSSStyleDeclaration, number>;

export { NullWrap, EventNames, EventHandler, Options, MoveBase, NoNumberCSSStyleDeclaration, RectInfo, RectBoundInfo, offsetInfo, momentumInfo };
